#include "PCH.h"
#include "Win32Client.h"
using namespace DeviousRenderer;


LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch (msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, msg, wparam, lparam);

}
Win32Client::Win32Client()
: m_hWnd(0)
, m_dWinStyle(WS_OVERLAPPEDWINDOW | WS_VISIBLE)
{

}

Win32Client::~Win32Client()
{

}

void Win32Client::DeferMessage()
{

}

void Win32Client::ProcessDeferredMessages()
{

}

void Win32Client::PumpOSMessage()
{

}

bool Win32Client::Init()
{
	WNDCLASSEX wc;

	//Setup
	memset(&wc, 0, sizeof(wc));
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WinProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = 0;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = TEXT("DiviousRenderer");
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	RegisterClassEx(&wc);
	
	RECT rc;
	rc.top = rc.left = 0;
	rc.right = m_iWidth;
	rc.bottom = m_iHeight;

	AdjustWindowRect(&rc, m_dWinStyle, false);
	long lWidth = rc.right - rc.left;
	long lHeight = rc.bottom - rc.top;

	long lLeft = (long)m_iLeft;
	long lTop = (long)m_iTop;

	m_hWnd = CreateWindowEx(
		NULL,
		wc.lpszClassName,
		m_sCaption.c_str(),
		m_dWinStyle,
		lLeft, lTop,
		lWidth, lHeight,
		NULL,
		NULL,
		NULL,
		NULL
		);

	if (m_hWnd)
	{
		ShowWindow(m_hWnd, SW_SHOWNORMAL);
		UpdateWindow(m_hWnd);
	}

	return true;
}

void Win32Client::Loop()
{
	MSG msg;
	bool bLoop = true;

	while( bLoop )
	{
		while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{ 
			if ( msg.message == WM_QUIT )
			{
				bLoop = false;
				break;
			}
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}

		// Call the overloaded application update function.
		Tick(0.0f);
	}
}

void Win32Client::Tick(float deltaTime)
{

}

void Win32Client::Exit()
{

}

void Win32Client::SetWidth(int width)
{
	m_iWidth = width;
	UpdateState();
}

void Win32Client::SetHeight(int height)
{
	m_iHeight = height;
	UpdateState();
}

void Win32Client::SetSize(int width, int height)
{
	m_iWidth = width;
	m_iHeight = height;
	UpdateState();
}

void Win32Client::SetPosition(int left, int top)
{
	m_iLeft = left;
	m_iTop = top;
	UpdateState();
}

void Win32Client::SetCaption(std::wstring& caption)
{
	m_sCaption = caption;
	if (m_hWnd != 0)
	{
		SetWindowText(m_hWnd, m_sCaption.c_str());
	}
}

int Win32Client::GetWidth()
{
	RECT rect;
	GetClientRect(m_hWnd, &rect);
	return (rect.right - rect.left);
}

int Win32Client::GetHeight()
{
	RECT rect;
	GetClientRect(m_hWnd, &rect);
	return (rect.bottom - rect.top);
}

int Win32Client::GetLeft()
{
	POINT point;
	point.x = 0;
	point.y = 0;

	ClientToScreen( m_hWnd, &point );

	return( point.x );
}

int Win32Client::GetTop()
{
	POINT point;
	point.x = 0;
	point.y = 0;

	ClientToScreen( m_hWnd, &point );

	return( point.y );
}

void Win32Client::UpdateState()
{
	if (m_hWnd != 0)
	{
		RECT ClientRect;
		ClientRect.left = 0;
		ClientRect.top = 0;
		ClientRect.right = m_iWidth;
		ClientRect.bottom = m_iHeight;

		RECT WinRect = ClientRect;
		AdjustWindowRect(&WinRect, m_dWinStyle, false);

		int deltaX = (WinRect.right - ClientRect.right) / 2;
		int deltaY = (WinRect.bottom - ClientRect.bottom) / 2;

		MoveWindow(m_hWnd, m_iLeft - deltaX, m_iTop - deltaY, m_iWidth + deltaX * 2, m_iHeight + deltaY * 2, true);
	}
}

